#ifndef INPUTGESTURESCALE_H_INCLUDED
#define INPUTGESTURESCALE_H_INCLUDED

#include "InputGestureBasicFingers.h"

#include <map>
#include "math.h"
#include <cmath>

namespace tuio

{

class ditsscale
{
    public:
    float tstamp;
    float x,y;
};

class TeventNewScale : public TTEvent <TeventNewScale>
{
    public:
    float scale;
    float x1, x2, y1, y2;
};


class InputGestureScale : public CanBasicFingers< tuioApp <InputGesture> >
{
    public:
    InputGestureBasicFingers * gesturefingers;
    std::map<int,ditsscale *> elsdits;
    float x_1, y_1, x_2, y_2, module_pre,ini_module;
    int32 id_1,id_2;
    int num_fingers;

    InputGestureScale()
    {
        gesturefingers = Singleton<InputGestureBasicFingers>::get();
        num_fingers=0;
    }

    virtual void ReceiveCall(const char * addr, osc::ReceivedMessageArgumentStream & argList)
    {
        std::list<TEvent*>::iterator it;
        for(it = gesturefingers->events.begin();
            it != gesturefingers->events.end();
            it++)
        {
            TEvent * e = *it;
            processTevent(e);
        }
    }

    //Interface redefined by ofApp
    void addTuioCursor(int32 id, float xpos,float ypos,float xspeed,float yspeed,float maccel)
    {
        ditsscale * d = new ditsscale();
        d->tstamp = ofGetElapsedTimef();
        d->x = xpos;
        d->y = ypos;
    	elsdits[id] = d;

        if(num_fingers == 0)
        {
            id_1 = id;
            num_fingers++;
        }
        else if (num_fingers == 1)
        {
            id_2 = id;
            num_fingers++;
            module_pre = ini_module = sqrt( pow((elsdits[id_1]->x-elsdits[id_2]->x),2) + pow((elsdits[id_1]->y-elsdits[id_2]->y),2 ));

        }
    }
    void updateTuioCursor(int32 id, float xpos,float ypos,float xspeed,float yspeed,float maccel)
    {
            if(num_fingers == 2)
            {

                if(id == id_1)
                {
                    float module = sqrt( pow(((elsdits[id_2]->x)-xpos),2) + pow(((elsdits[id_2]->y)-ypos),2 ));
                    TeventNewScale * evt = new TeventNewScale();
                    evt->scale =(module-module_pre)/ini_module;
                    evt->x2=elsdits[id_2]->x;
                    evt->x1= xpos;
                    evt->y2=elsdits[id_2]->y;
                    evt->y1= ypos;
                    events.push_back(evt);
                    module_pre = module;

                }

                if(id == id_2)
                {

                    float module = sqrt( pow(((elsdits[id_1]->x)-xpos),2) + pow(((elsdits[id_1]->y)-ypos),2 ));
                    TeventNewScale * evt = new TeventNewScale();
                    evt->scale =(module-module_pre)/ini_module;
                    evt->x1=elsdits[id_1]->x;
                    evt->x2= xpos;
                    evt->y1=elsdits[id_1]->y;
                    evt->y2= ypos;
                    events.push_back(evt);
                    module_pre = module;
                }
            }

    }
    void removeTuioCursor(int32 id)
    {
        if (id_1 == id)
        {
            id_1 = id_2;
            num_fingers--;
        }
        else if (id_2 == id)
        {
            id_2 = 0;
            num_fingers--;
        }
    }

};

template<class Base>
class CanScale : public Base
{
    public:
  ///Interficie
  virtual void newScale(float sc, float x1, float x2, float y1, float y2){}

  ///Handlers
  TEventHandler(TeventNewScale)
  {
      TeventNewScale * e = static_cast<TeventNewScale *>(evt);
      newScale(e->scale, e->x1, e->x2, e->y1, e->y2);

  }

  ///Register
  CanScale()
  {
      TRegistraCallback(CanScale,TeventNewScale);
      registerMeToInputGestureManager(Singleton<InputGestureScale>::get());
  }

    eventprocessorsType & getEP()
    {
        return Base::getEP();
    }

};

}

#endif // INPUTGESTURESCALE_H_INCLUDED
